package com.mapflow.geo.common.manager;

import java.util.List;

import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.mapflow.geo.common.dao.UserDao;
import com.mapflow.geo.common.model.entities.User;
import com.mapflow.geo.common.service.UserExistsException;

/**
 * Business Service Interface to handle communication between web and persistence layer.
 * 
 * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a> Modified by <a
 *         href="mailto:dan@getrolling.com">Dan Kibler </a>
 */
public interface UserManager extends GenericManager<User, Long> {

  /**
   * Convenience method for testing - allows you to mock the DAO and set it on an interface.
   * 
   * @param userDao
   *          the UserDao implementation to use
   */
  void setUserDao(UserDao userDao);

  /**
   * Retrieves a user by userId. An exception is thrown if user not found
   * 
   * @param userId
   *          the identifier for the user
   * @return User
   */
  User getUser(String userId);

  /**
   * Finds a user by their username.
   * 
   * @param username
   *          the user's username used to login
   * @return User a populated user object
   * @throws org.springframework.security.core.userdetails.UsernameNotFoundException
   *           exception thrown when user not found
   */
  User getUserByUsername(String username) throws UsernameNotFoundException;

  /**
   * Retrieves a list of all users.
   * 
   * @return List
   */
  List<User> getUsers();

  /**
   * Saves a user's information.
   * 
   * @param user
   *          the user's information
   * @throws UserExistsException
   *           thrown when user already exists
   * @return user the updated user object
   */
  User saveUser(User user) throws UserExistsException;

  /**
   * Removes a user from the database by their userId
   * 
   * @param userId
   *          the user's id
   */
  void removeUser(String userId);

  /**
   * Search a user for search terms.
   * 
   * @param searchTerm
   *          the search terms.
   * @return a list of matches, or all if no searchTerm.
   */
  List<User> search(String searchTerm);
}
